package com.hcbd.tdwt;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.GnssStatus;
import android.location.GpsStatus;
import android.location.LocationManager;
import android.location.OnNmeaMessageListener;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;

import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.hcbd.tdwt.base.AuthManger;
import com.hcbd.tdwt.base.BaseActivity;
import com.hcbd.tdwt.base.BdManager;
import com.hcbd.tdwt.base.BeidouBoxParams;
import com.hcbd.tdwt.base.Constant;
import com.hcbd.tdwt.base.GlobalParams;
import com.hcbd.tdwt.base.ImgSendManager;
import com.hcbd.tdwt.base.bd.BdToolFactory;
import com.hcbd.tdwt.util.AppUtil;
import com.hcbd.tdwt.util.BDToGPS;
import com.hcbd.tdwt.util.DateUtils;
import com.hcbd.tdwt.util.MyCrashHandler;
import com.hcbd.tdwt.util.SharedPreferencesUtil;
import com.hcbd.tdwt.util.StringUtil;
import com.hcbd.tdwt.util.SunRiseSet;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;


import com.pangu.bdsdk2021.entity.terminalthree.BDSnrInfo;
import com.pangu.bdsdk2021.entity.terminaltwo.BDGGAInfo;
import com.pangu.bdsdk2021.entity.terminaltwo.BDGSVInfo;
import com.pangu.bdsdk2021.entity.terminaltwo.BDRMCInfo;
import com.pgyersdk.Pgyer;
import com.hcbd.tdwt.ui.xingyu.dialog.LoadingDialog;
import com.hcbd.tdwt.ui.xingyu.vo.BoxContact;
import com.hcbd.tdwt.ui.xingyu.vo.BoxContact_Table;

import com.raizlabs.android.dbflow.config.FlowConfig;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.hcbd.tdwt.ui.xingyu.vo.PositionVo;

import org.greenrobot.eventbus.EventBus;
import org.osmdroid.util.GeoPoint;
import java.util.Calendar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import static android.widget.Toast.makeText;


public class MainApp extends Application {
    private static MainApp mainApp;
    private String TAG = "MainApp";
    //当前所显示的Activity
    public BaseActivity mActivity;
    public Toast mToast;
    public SharedPreferencesUtil sp;
    public LoadingDialog mProgressDialog;//加载弹框
    public PowerManager.WakeLock wakeLock = null;

    public static MainApp getInstance() {
        return mainApp;
    }
    @SuppressLint("InvalidWakeLockTag")
    @Override
    public void onCreate() {
        super.onCreate();
        mainApp=this;
        sp=new SharedPreferencesUtil(this);
        AuthManger.getAuthManger().init(this);
        FlowManager.init(new FlowConfig.Builder(this).build());
        initColleteCrash();
//        initSystemLocation();
        initMap();
        initPosMode();
        initChannelNumber();
//        wakeLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakeLock");
//        if(wakeLock!=null) wakeLock.acquire();

        //testInit();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
                Log.e(TAG, "onActivityCreated: 打开页面 "+activity.getLocalClassName());
            }
            @Override public void onActivityStarted(@NonNull Activity activity) {}
            @Override public void onActivityResumed(@NonNull Activity activity) {}
            @Override public void onActivityPaused(@NonNull Activity activity) {}
            @Override public void onActivityStopped(@NonNull Activity activity) {}
            @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {}
            @Override public void onActivityDestroyed(@NonNull Activity activity) {
                Log.e(TAG, "onActivityDestroyed: 关闭页面 "+activity.getLocalClassName());
            }
        });


    }
    void testInit(){
        BeidouBoxParams.sendFreq=1;
        BeidouBoxParams.cardType=5;
        BeidouBoxParams.card_model=2;
        BeidouBoxParams.userCardNumber="1234567";
        BdManager.getInstance().initSendSize();
        BeidouBoxParams.isBoxConnectNormal=true;
        BDSnrInfo.obj.s1=40;
    }
    @Override
    protected void attachBaseContext(Context context) {
        super.attachBaseContext(context);
        Pgyer.setAppId("2ade5f0670f1d998764f2b8e544a3b68");
    }

    /**
     * Toast的工具方法
     *
     * @param msg
     */
    @SuppressLint("ShowToast")
    public void showMsg(final String msg) {
        mActivity.runOnUiThread(() -> {
            if (null == mToast) {
                mToast = makeText(mActivity, msg, Toast.LENGTH_SHORT);
            } else {
                mToast.cancel();mToast = null;
                mToast = makeText(mActivity, msg, Toast.LENGTH_SHORT);
//                mToast.setText(msg);
            }
            mToast.show();

        });
    }
    @SuppressLint("ShowToast")
    public void showMsgLong(final String msg) {
        mActivity.runOnUiThread(() -> {
            Toast.makeText(mActivity, msg, Toast.LENGTH_LONG).show();
            Log.e("mainapp  OK ", "showMsgLong: " );
        });
    }
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = null;

    public void setLocationInfoInterface(LocationInfoInterface locationInfoInterface){
        this.locationInfoInterface=locationInfoInterface;
    }
    public LocationInfoInterface locationInfoInterface;
    public interface LocationInfoInterface {
        //定位信息
        void LocationInfo();
    }

    OnNmeaMessageListener onNmeaMessageListener= (s, l) -> {
        receivedNmea(s);
    };
    GpsStatus.NmeaListener mNmeaListener = (arg0, instruc) -> {
        receivedNmea(instruc);
    };
    private ExecutorService executorService;
    public void receivedNmea(String instruc){
        executorService.submit(new Runnable() {
            @Override
            public void run() {
//                int source = sp.getAttributeInt(Constant.DATA_SOURCES);
//                if(source!=-1){
//                    Log.i(TAG, "通过串口获取");
//                    return;
//                }
                Log.i(TAG, "系统api原始RN: "+instruc);
                if(instruc.contains("GGA")){
                    convertGGAInfo(instruc);
                }else if(instruc.contains("RMC")){
                    convertRMCInfo(instruc);
                }else if(instruc.contains("GSV")){
                    convertGSVInfo(instruc);
                }
            }
        });

    }
    private LocationManager mLocationManager;
    public void initSystemLocation(){
        if(executorService==null){executorService = Executors.newFixedThreadPool(4);}
        if (mLocationManager == null)
            mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mLocationManager.addNmeaListener(onNmeaMessageListener);
        } else {
            mLocationManager.addNmeaListener(mNmeaListener);
        }
    }
    public void closeSystemLocation(){
        if (mLocationManager != null){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                mLocationManager.removeNmeaListener(onNmeaMessageListener);
            } else {
                mLocationManager.removeNmeaListener(mNmeaListener);
            }
            mLocationManager=null;
        }
    }
    public void convertGGAInfo(String instruc){
        try {
            int xorIndex = instruc.indexOf("*");
            if (xorIndex != -1) {
                instruc = instruc.substring(0, xorIndex);
            }
            String[] instrucs = instruc.split(",",-1);
            if (instrucs.length < 15) {
                return;//长度不足视为无效数据'
            }
            BDGGAInfo bdggaInfo=new BDGGAInfo();
            bdggaInfo.positioningMoment=instrucs[1];
            bdggaInfo.latitude=instrucs[2];
            bdggaInfo.latitudeDirection=instrucs[3];
            bdggaInfo.longitude=instrucs[4];
            bdggaInfo.longitudeDirection=instrucs[5];
            bdggaInfo.statusIndication=instrucs[6];
            bdggaInfo.visibleSatellite=instrucs[7];
            bdggaInfo.hdop=instrucs[8];
            bdggaInfo.antennaHeight=instrucs[9];
            bdggaInfo.antennaHeightUnit=instrucs[10];
            bdggaInfo.abnormalElevation=instrucs[11];
            bdggaInfo.satelliteSigLockStatusUnit=instrucs[12];
            bdggaInfo.differentialDataAge=instrucs[13];
            bdggaInfo.differentialStationID=instrucs[14];
            BdManager.getInstance().onGGAInfo(bdggaInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void convertGSVInfo(String instruc){
        try{
            int xorIndex = instruc.indexOf("*");
            if (xorIndex != -1) {
                instruc = instruc.substring(0, xorIndex);
            }
            String[] instrucs = instruc.split(",",-1);
            if (instrucs.length < 20) return;//长度不足视为无效数据'
            BDGSVInfo bdgsvInfo = new BDGSVInfo();
            bdgsvInfo.satellitesType = instrucs[0];
            bdgsvInfo.totalNumber = instrucs[1];
            bdgsvInfo.statementNumber = instrucs[2];
            bdgsvInfo.satellitesNumber = instrucs[3];
            bdgsvInfo.sv1 = instrucs[4];
            bdgsvInfo.elv1 = instrucs[5];
            bdgsvInfo.azl1 = instrucs[6];
            bdgsvInfo.cno1 = instrucs[7];
            bdgsvInfo.sv2 = instrucs[8];
            bdgsvInfo.elv2 = instrucs[9];
            bdgsvInfo.azl2 = instrucs[10];
            bdgsvInfo.cno2 = instrucs[11];
            bdgsvInfo.sv3 = instrucs[12];
            bdgsvInfo.elv3 = instrucs[13];
            bdgsvInfo.azl3 = instrucs[14];
            bdgsvInfo.cno3 = instrucs[15];
            bdgsvInfo.sv4 = instrucs[16];
            bdgsvInfo.elv4 = instrucs[17];
            bdgsvInfo.azl4 = instrucs[18];
            bdgsvInfo.cno4 = instrucs[19];
            BdManager.getInstance().onGSVInfo(bdgsvInfo);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public void convertRMCInfo(String instruc) {
        try{
            String[] instrucs = instruc.split(",", -1);
            if (instrucs.length >= 7) {
                BDRMCInfo bdrmcInfo = new BDRMCInfo();
                bdrmcInfo.utcTime = instrucs[1];
                bdrmcInfo.positionStatus = instrucs[2];
                bdrmcInfo.latitude = instrucs[3];
                bdrmcInfo.latitudeDirection = instrucs[4];
                bdrmcInfo.longitude = instrucs[5];
                bdrmcInfo.longitudeDirection = instrucs[6];
                bdrmcInfo.groundSpeed = instrucs[7];
                bdrmcInfo.groundHeading = instrucs[8];
                bdrmcInfo.date = instrucs[9];
                bdrmcInfo.magneticDeclination = instrucs[10];
                bdrmcInfo.magneticDeclinationDirection = instrucs[11];
                bdrmcInfo.modeIndication = instrucs[12];
                BdManager.getInstance().onRMDInfo(bdrmcInfo);
            }
        } catch (Exception e){
            e.printStackTrace();
        }

    }


    //声明定位回调监听器
    // 单北斗模块无法从系统获取定位
    public AMapLocationListener mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            //位置发生变化
            if (aMapLocation != null) {
//                if (aMapLocation.getErrorCode() == 0) {
//                    showMsg("系统api定位变化："+aMapLocation.getLongitude()+"/"+aMapLocation.getLatitude());
//                    Log.e(TAG, "位置发生变化: "+aMapLocation.getLongitude()+"/"+aMapLocation.getLatitude());
//                    if (AppUtil.isFastLoction(5000)) {
//                        return;
//                    }
//                    GlobalParams.gpsLongitude = aMapLocation.getLongitude();
//                    GlobalParams.gpsLatitude = aMapLocation.getLatitude();
//                    GeoPoint latLon = new GeoPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());
//                    GeoPoint newLatlon = BDToGPS.castFromOtherPoint(latLon, 1);
//                    BeidouBoxParams.gpsLatDou= StringUtil.reservedLoc(newLatlon.getLatitude(),6);
//                    BeidouBoxParams.gpsLonDou=StringUtil.reservedLoc(newLatlon.getLongitude(),6);
//                    int format = sp.getAttributeInt(Constant.LATITUDE_AND_LONGITUDE_FORMAT);
//                    if(Constant.DEGREE_MINUTES_SECONDS_FORMAT== format){
//                        BeidouBoxParams.gpsLatitude =StringUtil.changeToDFM(BeidouBoxParams.gpsLatDou);
//                        BeidouBoxParams.gpsLongitude =StringUtil.changeToDFM(BeidouBoxParams.gpsLonDou);
//                    }else if(Constant.DEGREE_FORMAT== format){
//                        BeidouBoxParams.gpsLatitude =String.valueOf(BeidouBoxParams.gpsLatDou);
//                        BeidouBoxParams.gpsLongitude =String.valueOf(BeidouBoxParams.gpsLonDou);
//                    }
//                    BeidouBoxParams.gpsAltitude = aMapLocation.getAltitude();
//                    BeidouBoxParams.speed =aMapLocation.getSpeed();
//                    BeidouBoxParams.bearing =aMapLocation.getBearing();
//                    if("".equals(BeidouBoxParams.sunRise)){
//                        BeidouBoxParams.sunRise = SunRiseSet.getSunrise(latLon, Calendar.getInstance());
//                        BeidouBoxParams.sunSet = SunRiseSet.getSunset(latLon, Calendar.getInstance());
//                    }
//                    if(BdToolFactory.MOBILE_PHONE_TYPE==BdToolFactory.ORDINARY_MOBILE_PHONE){
//                        PositionVo position = new PositionVo();
//                        position.setLongitude(BeidouBoxParams.gpsLonDou);
//                        position.setLatitude(BeidouBoxParams.gpsLatDou);
//                        position.setSpeed(BeidouBoxParams.speed);
//                        position.setBearing( BeidouBoxParams.bearing);
//                        position.setAltitude(BeidouBoxParams.gpsAltitude);
//                        position.setTime(Long.parseLong(DateUtils.getTimeStamp()));
//                        if (GlobalParams.positions.size() > 600) {
//                            GlobalParams.positions.remove(0);
//                        }
//                        GlobalParams.positions.add(position);
//                    }
//                    if(locationInfoInterface!=null){//定位信息回调
//                        locationInfoInterface.LocationInfo();
//                    }
//                } else {
//                    Log.e("AMapMessage", "ErrCode:" + aMapLocation.getErrorCode() + "  ErrInfo:" + aMapLocation.getErrorInfo());
//                }
            }
        }
    };

    /**
     * 初始化化高德地图
     */
    public void initMap() {
        //初始化定位
        mLocationClient = new AMapLocationClient(this);
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
        mLocationOption = new AMapLocationClientOption();
        //高精度模式(Hight_Accuracy)、低功耗模式(Battery_Saving)、仅设备模式(Device_Sensors)
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Device_Sensors);
        //设置定位场景，目前支持三种场景（签到、出行、运动，默认无场景）
        mLocationOption.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.Transport);
        //获取最近3s内精度最高的一次定位结果：设置setOnceLocationLatest(boolean b)接口为true，启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true，setOnceLocation(boolean b)接口也会被设置为true，反之不会，默认为false。
        mLocationOption.setOnceLocationLatest(true);
        //设置定位间隔,单位毫秒,默认为2000ms，最低1000ms。
        mLocationOption.setInterval(6000);
        //设置是否返回地址信息（默认返回地址信息）
        mLocationOption.setNeedAddress(false);
        //设置是否允许模拟位置,默认为true，允许模拟位置
        mLocationOption.setMockEnable(true);
        //单位是毫秒，默认30000毫秒，建议超时时间不要低于8000毫秒。
        mLocationOption.setHttpTimeOut(30000);
        //关闭缓存机制
        mLocationOption.setLocationCacheEnable(false);
        if (null != mLocationOption) {
            mLocationClient.setLocationOption(mLocationOption);
            //设置场景模式后最好调用一次stop，再调用start以保证场景模式生效
            mLocationClient.stopLocation();
            mLocationClient.startLocation();
        } else {
            //给定位客户端对象设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            //启动定位
            mLocationClient.startLocation();
        }
    }
    private static AtomicInteger atomicInteger;
    /**
     * 发送倒计时
     */
    @SuppressLint("StaticFieldLeak")
    public void startNewSentWaitSecTimer() {
        if (BeidouBoxParams.sentWaitSec != 0) {
            // 防止在不空闲的时候产生新的倒计时线程，这样会混乱计时器
            return;
        }

        new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected Boolean doInBackground(Void... params) {
                // 设置频度
                if (BeidouBoxParams.sendFreq != -1) {
                    BeidouBoxParams.sentWaitSec = BeidouBoxParams.sendFreq;
                    if(ImgSendManager.getInstance().isSend()){//如果是图片发送则增加四秒
                        BeidouBoxParams.sentWaitSec +=ImgSendManager.delaySeconds;
                    }
                } else {
                    BeidouBoxParams.sentWaitSec = 60;
                }
                atomicInteger = new AtomicInteger(BeidouBoxParams.sentWaitSec);
                while (true) {
                    if (BeidouBoxParams.sentWaitSec < 0) {
                        BeidouBoxParams.sentWaitSec = 0;
                    }
                    EventBus.getDefault().post(BeidouBoxParams.sentWaitSec);
                    if (BeidouBoxParams.sentWaitSec == 0) {
                        return false;
                    }
                    // 自减（安全线程）
                    BeidouBoxParams.sentWaitSec = atomicInteger.decrementAndGet();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            protected void onPostExecute(Boolean result) {
                super.onPostExecute(result);

            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    /**
     * 通知栏消息
     *
     * @param content String
     */
    public void processCustomMessage(String content) {
        if (AppUtil.isAppForeground()) return;
        String channelID = "1";
        String channelName = "channel_name";
        // 跳转的Activity
        Intent msgIntent = mainApp.getPackageManager().getLaunchIntentForPackage("com.bdtx.tdwt");//获取启动Activity
        PendingIntent pendingIntent = PendingIntent.getActivity(mainApp, 0, msgIntent, 0);
        // 获得系统推送的自定义消息
        NotificationManager notificationManager = (NotificationManager) mainApp.getSystemService(NOTIFICATION_SERVICE);
        //适配安卓8.0的消息渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }
        NotificationCompat.Builder notification = new NotificationCompat.Builder(mainApp, channelID);
        notification.setAutoCancel(true)
                .setContentText(content)
                .setContentTitle(getResources().getString(R.string.app_name))
                .setSmallIcon(R.mipmap.logo)
                .setDefaults(Notification.DEFAULT_ALL)
                .setContentIntent(pendingIntent);
        notificationManager.notify((int) (System.currentTimeMillis() / 1000), notification.build());
    }
    /**
     * 状态倒计时，超过指定时间未收到终端回执则为失败
     */
    public void startSentStatusWaitSecTimer() {
        Handler delayHandler = new Handler();
        delayHandler.postDelayed(() -> {
            //本地数据库存储
            if (BeidouBoxParams.lastMsg == null) return;
            if (Constant.SEND_MSG_WAIT== BeidouBoxParams.lastMsg.getStatus()) {
                BeidouBoxParams.lastMsg.setStatus(Constant.SEND_MSG_FAIL);
                BeidouBoxParams.lastMsg.update();
                BeidouBoxParams.lastMsg = null;
            }
        }, 20000);
    }
    /**
     * 获取位置上报序列号
     *
     * @return int
     */
    public int getLocationSerial() {
        int msgID = getConfig().getInt("getLocationSerial", 0);
        if (msgID >= 256) {
            msgID = 0;
        } else {
            msgID++;
        }
        getConfig().edit().putInt("getLocationSerial", msgID).apply();
        return msgID;
    }
    public SharedPreferences getConfig() {
        return getSharedPreferences("config", MODE_PRIVATE);
    }
    public  void initColleteCrash() {
        //初始化Handler,收集java层崩溃
        MyCrashHandler handler = new MyCrashHandler();
        Thread.setDefaultUncaughtExceptionHandler(handler);
    }




    /**
     * 显示加载框
     */
    public void showLoading(String msg) {
        if (mProgressDialog == null) return;
        if (!mProgressDialog.isShowing()) {
            mProgressDialog.setTips(msg);
            mProgressDialog.show();
        }
    }

    /**
     * 隐藏加载框
     */
    public void hideLoading() {
        if (mProgressDialog == null) return;
        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }
    //默认经纬度和定位模式
    public void initPosMode(){
        String mode=sp.getAttribute(Constant.POSITION_MODE);
        if("".equals(mode)){
            sp.addAttribute(Constant.POSITION_MODE,Constant.PHONE_POS);
        }
        int from=sp.getAttributeInt(Constant.LATITUDE_AND_LONGITUDE_FORMAT);
        if(from==-1){
            sp.addAttribute(Constant.LATITUDE_AND_LONGITUDE_FORMAT,Constant.DEGREE_MINUTES_SECONDS_FORMAT);
        }
    }
    //默认通道数
    public void initChannelNumber(){
        String number=sp.getAttribute(Constant.PLATFORM_CENTER_NUMBER);
        if("".equals(number)){
            sp.addAttribute(Constant.PLATFORM_CENTER_NUMBER,Constant.PLATFORM_3);
            GlobalParams.rdCentreNumber=Constant.PLATFORM_3;
        }else{
            GlobalParams.rdCentreNumber=number;
        }
        BoxContact boxContact= SQLite.select().from(BoxContact.class).where(BoxContact_Table.id.eq(1)).querySingle();
        if(boxContact==null){
            BoxContact boxContact1=new BoxContact();
            boxContact1.setId(1);
            boxContact1.setName("指挥中心");
            boxContact1.setBoxId(GlobalParams.commandCentreNumber);
            boxContact1.setLastTimeContent(getString(R.string.welcome_to)+getString(R.string.app_name));
            boxContact1.setUnReadNewsNum(0);
            boxContact1.setRecentCommunicationTime(DateUtils.CalendarToString(Calendar.getInstance(), null));
            boxContact1.insert();
        }
    }
}
